package com.example.reagent_management.ui.operatedialog.dialogs

import android.util.Log
import android.view.View
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import com.example.lib_base.base.BaseDBDialogFragment
import com.example.lib_base.base.DataBindingConfig
import com.example.lib_base.widget.InputTextManager
import com.example.reagent_management.AppEvent
import com.example.reagent_management.BR
import com.example.reagent_management.R
import com.example.reagent_management.databinding.FragmentOutstoreBinding
import com.example.reagent_management.room.entity.ReagentInformation
import com.example.reagent_management.room.entity.ReagentOperate
import com.example.reagent_management.service.works.HistoryWork
import com.example.reagent_management.service.works.WorksBuild
import com.example.reagent_management.service.works.setHistoryData
import com.example.reagent_management.ui.operatedialog.viewmodle.StoreViewModel
import com.hjq.toast.ToastUtils
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import java.util.*
import javax.inject.Inject

@AndroidEntryPoint
class OutStoreFragment : BaseDBDialogFragment() {
    private var reagentId = -1L
    private val mState: StoreViewModel by viewModels()
    private lateinit var mEvent: AppEvent

    @Inject
    lateinit var worksBuild: WorksBuild

    //入库数
    private var count = 0L

    //入库的Id  出库的"counts"关联入库id 为方便不起新字段以及方便回退操作
    private var inStoreId = 0L

    override fun getDataBindingConfig(): DataBindingConfig? {
        mEvent = getApplicationScopeViewModel(AppEvent::class.java)
        return DataBindingConfig(R.layout.fragment_outstore, BR.VM, mState)
            .addBindingParam(BR.Event, mEvent)
    }

    override fun initViewOrObserve() {
        setTransAndHeight(true, 0.5f)
        val operate = ReagentOperate()
        with(getBinding() as FragmentOutstoreBinding) {
            mEvent.inStoreChoose.observe(viewLifecycleOwner) {
                counts.hint = "最大出库数为${it.inCounts}"
                count = it.inCounts
                batchNumber.text = it.batch
                inStoreId = it.id
                //供应商 批号
                operate.supplier = it.supplier
                operate.batchNumber = it.batch
            }
            InputTextManager.with(lifecycleOwner)
                .addView(reagentName)
                .addView(reagentType)
                .addView(batchNumber)
                .addView(counts)
                .setMain(ok)
                .build()
            no.setOnClickListener {
                dismissAllowingStateLoss()
            }
            //选试剂信息 未避免代码判断麻烦,界面开始就让先选试剂信息 毕竟取试剂时试剂信息最重要
            chooseName.setOnClickListener {
                val storeChooseFragment = StoreChooseFragment()
                storeChooseFragment.show(childFragmentManager, "StoreChooseFragment")
                //拿到弹窗返回的数据  其实可以把回调数据放在共享通信总线中，让总线viewModel驱动UI ，跟在activity/fragment中控制一样的
                //只不过controller可能会更直接？毕竟不是compose还要到xml中查看binding的数据，不过都是看代码...
                storeChooseFragment.setOnDataListener { it1 ->
                    if (it1 is ReagentInformation) {
                        it1.let {
                            this.reagentName.text = it.reagentName
                            this.reagentType.text = it.reagentType
                            if (reagentId != it.reagent_id) {
                                //若重选选了其他,试剂批号置空
                                batchNumber.text = ""
                            }
                            reagentId = it.reagent_id
                            chooseBatch.visibility = View.VISIBLE
                        }
                    }
                }
            }
            //选择试剂批号  使用通信总线
            chooseBatch.setOnClickListener {
                val inStoreChoose = InStoreChooseFragment()
                inStoreChoose.updateData(reagentId)
                inStoreChoose.show(childFragmentManager, "InStoreChooseFragment")
            }
            //插入 更新 记录 出库操作
            ok.setOnClickListener {
                no.isClickable = false
                ok.isClickable = false
                val outCounts = counts.text.toString().toLong()
                if (outCounts > count) {
                    ToastUtils.show("出库数不能大于入库数~")
                    no.isClickable = true
                    ok.isClickable = true
                    return@setOnClickListener
                }
                operate.reagent_info = reagentId
                Log.e(TAG, "出库数: $outCounts")
                operate.num = outCounts
                operate.counts = inStoreId
                operate.operate = false
                //IO操作
                lifecycleScope.launch(Dispatchers.IO) {
                    //插入结果
                    operate.days = Calendar.getInstance().time.time
                    val result = mState.insertOperate(operate)
                    if (result != -1L) {
                        val updateAllCounts = this.async {
                            //更新入库[试剂名+试剂信息]的总数 这里必不空
                            val allCounts =
                                mState.getLastCounts(operate.batchNumber, operate.reagent_info)
                            val allCountsResult = mState.updateLastCounts(
                                allCounts!!.counts - outCounts,
                                allCounts.operate_id
                            )
                            Log.e(TAG, "更新[试剂名+试剂信息]的总数:${allCounts.counts} ")
                            return@async Pair(allCountsResult, allCounts.counts - outCounts)
                        }
                        val updateInStore = this.async {
                            //更新入库的数量
                            Log.e(TAG, "入库的数量前的数量: $count")
                            return@async mState.updateInStore(count - outCounts, inStoreId)
                        }
                        val historyWork = this.async(coroutineContext, CoroutineStart.LAZY) {
                            //需要总数的值
                            worksBuild.Builder().setInputData(setHistoryData(
                                arrayOf(reagentName.text.toString(), operate.batchNumber),
                                longArrayOf(
                                    updateAllCounts.await().second, reagentId, result,outCounts
                                ),
                                false
                            ),HistoryWork::class.java).build()
                            ToastUtils.show("出库成功")
                            dismissAllowingStateLoss()
                        }
                        if (updateAllCounts.await().first != -1 && updateInStore.await() != -1) {
                            historyWork.await()
                        }
                    } else {
                        ToastUtils.show("出库失败")
                    }
                }
            }
        }
    }


}